# -*- coding: utf-8 -*-
import os

import numpy as np
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (QDialog, QVBoxLayout, QHBoxLayout, QGridLayout,
                             QWidget, QLabel, QFrame, QTextEdit,
                             QTabWidget, QPushButton,  QFileDialog, QMessageBox)
from PyQt5.QtCore import Qt, QTimer, QPropertyAnimation

import matplotlib
matplotlib.use('Qt5Agg')
import matplotlib.pyplot as plt
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import seaborn as sns
from datetime import datetime
import json
import platform
# ============ 字体配置解决方案 ============
# ============ 字体配置解决方案 ============
# ============ 字体配置解决方案 ============
import os
import warnings
import matplotlib.font_manager as fm
warnings.filterwarnings('ignore')

# 创建全局字体属性对象
font_path = r'D:\projects\river\Font\platech.ttf'
if os.path.exists(font_path):
    fm.fontManager.addfont(font_path)
    custom_font = fm.FontProperties(fname=font_path)
    font_name = custom_font.get_name()
    plt.rcParams['font.sans-serif'] = [font_name]
    plt.rcParams['axes.unicode_minus'] = False
    print(f"已配置platech字体: {font_name}")
else:
    custom_font = fm.FontProperties()
    print("字体文件不存在，使用默认字体")

def configure_matplotlib_fonts():
    """配置matplotlib字体以支持中文和特殊字符"""
    pass  # 现在这个函数不需要做任何事，因为已经在上面配置了


# 调用字体配置
configure_matplotlib_fonts()

# ============ 简化字符版本的函数 ============
class SafeTextRenderer:
    """安全的文本渲染器，处理字体兼容性问题"""

    @staticmethod
    def safe_title(title):
        """安全的标题渲染，移除可能有问题的emoji"""
        # 移除emoji，保留中文和基础符号
        safe_mapping = {
            '🌊': '[水质]',
            '📊': '[统计]',
            '🏠': '[总览]',
            '🗺️': '[空间]',
            '🧠': '[智能]',
            '📋': '[报告]',
            '🔍': '[分析]',
            '🎯': '[目标]',
            '📈': '[趋势]',
            '🥧': '[分布]',
            '⏱️': '[时间]',
            '🔥': '[热力]',
            '🏭': '[污染]',
            '⚡': '[风险]',
            '🎨': '[聚类]',
            '🔗': '[关联]',
            '📁': '',
            '🔄': '[刷新]',
            '❌': '[关闭]',
            '💾': '[导出]',
            '✅': '[正常]',
            '⚠️': '[警告]',
            '🚨': '[严重]'
        }

        result = title
        for emoji, replacement in safe_mapping.items():
            result = result.replace(emoji, replacement)

        return result

# 创建全局实例
safe_text = SafeTextRenderer()

# 设置seaborn样式（简化版）
try:
    sns.set_style("whitegrid")
    sns.set_palette("husl")
except:
    pass  # 如果seaborn配置失败，继续运行

class AnimatedCanvas(FigureCanvas):
    """带动画效果的图表画布"""

    def __init__(self, parent=None, width=8, height=6, dpi=100):
        self.fig = Figure(figsize=(width, height), dpi=dpi)
        super().__init__(self.fig)
        self.setParent(parent)

        # 设置背景
        self.fig.patch.set_facecolor('#1e2329')
        self.setStyleSheet("""
            QWidget {
                background-color: #1e2329;
                border: 2px solid #00e6ff;
                border-radius: 12px;
            }
        """)


class WaterQualityAnalyzer:
    """智能水质分析评估器"""

    def __init__(self):
        # 垃圾类型权重配置（基于环境危害程度）
        self.pollution_weights = {
            'plastic-bag': 0.9,  # 塑料袋 - 极高危害
            'plastic-garbage': 0.85,  # 塑料垃圾 - 高危害
            'bottle': 0.7,  # 瓶子 - 中高危害
            'milk-box': 0.6,  # 奶盒 - 中等危害
            'ball': 0.4,  # 球 - 低危害
            'branch': 0.2,  # 树枝 - 很低危害（天然）
            'grass': 0.1,  # 草 - 极低危害（天然）
            'leaf': 0.05  # 叶子 - 几乎无害（天然）
        }

        # 水质等级标准
        self.quality_levels = {
            (0, 0.1): {'level': 'A', 'desc': '优秀', 'color': '#00ff88', 'advice': '水质极佳，生态环境良好'},
            (0.1, 0.3): {'level': 'B', 'desc': '良好', 'color': '#7ed321', 'advice': '水质良好，轻微污染'},
            (0.3, 0.5): {'level': 'C', 'desc': '一般', 'color': '#f5a623', 'advice': '水质一般，需要注意'},
            (0.5, 0.7): {'level': 'D', 'desc': '较差', 'color': '#ff8c00', 'advice': '水质较差，建议治理'},
            (0.7, 1.0): {'level': 'E', 'desc': '极差', 'color': '#ff4757', 'advice': '水质严重污染，急需处理'}
        }

    def calculate_pollution_index(self, detection_data):
        """计算污染指数"""
        total_score = 0
        total_items = len(detection_data)

        if total_items == 0:
            return 0

        for item in detection_data:
            category = item['category']
            confidence = item['confidence'] / 100  # 转换为0-1范围
            weight = self.pollution_weights.get(category, 0.5)

            # 污染贡献 = 类型权重 × 置信度 × 密度因子
            total_score += weight * confidence

        # 归一化污染指数
        pollution_index = min(total_score / total_items, 1.0)
        return pollution_index

    def assess_water_quality(self, pollution_index):
        """评估水质等级"""
        for (min_val, max_val), quality_info in self.quality_levels.items():
            if min_val <= pollution_index < max_val:
                return quality_info
        return self.quality_levels[(0.7, 1.0)]  # 默认最差等级

    def generate_analysis_report(self, stats_data, pollution_index, quality_info):
        """生成智能分析报告"""
        report = {
            'timestamp': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
            'overall_assessment': quality_info,
            'pollution_index': pollution_index,
            'key_findings': self._analyze_key_findings(stats_data),
            'recommendations': self._generate_recommendations(stats_data, pollution_index)
        }
        return report

    def _analyze_key_findings(self, stats_data):
        """分析关键发现"""
        findings = []

        # 检测数量分析
        if stats_data['total_detections'] > 50:
            findings.append("⚠️ 检测到大量垃圾，污染程度较严重")
        elif stats_data['total_detections'] > 20:
            findings.append("🔍 检测到中等数量垃圾，需要关注")
        else:
            findings.append("✅ 检测到少量垃圾，整体情况较好")

        # 塑料污染分析
        plastic_items = stats_data['category_counts'].get('plastic-bag', 0) + \
                        stats_data['category_counts'].get('plastic-garbage', 0) + \
                        stats_data['category_counts'].get('bottle', 0)

        if plastic_items > stats_data['total_detections'] * 0.6:
            findings.append("🚨 塑料污染严重，对生态环境威胁巨大")
        elif plastic_items > stats_data['total_detections'] * 0.3:
            findings.append("⚠️ 存在塑料污染，需要重点治理")

        # 置信度分析
        avg_conf = stats_data['avg_confidence']
        if avg_conf > 80:
            findings.append("🎯 检测结果置信度很高，数据可靠")
        elif avg_conf > 60:
            findings.append("📊 检测结果置信度良好")
        else:
            findings.append("⚠️ 检测结果置信度偏低，建议复查")

        return findings

    def _generate_recommendations(self, stats_data, pollution_index):
        """生成改善建议"""
        recommendations = []

        if pollution_index > 0.7:
            recommendations.extend([
                "🚨 立即启动应急清理方案",
                "📞 联系环保部门进行专业处理",
                "🔒 暂停水体使用，避免进一步污染"
            ])
        elif pollution_index > 0.5:
            recommendations.extend([
                "🧹 安排定期清理作业",
                "📋 制定污染源控制计划",
                "👥 加强周边监管和宣传"
            ])
        else:
            recommendations.extend([
                "🌱 保持现有管理水平",
                "🔍 继续定期监测",
                "📚 开展生态保护教育"
            ])

        # 基于主要污染类型的建议
        top_category = max(stats_data['category_counts'],
                           key=stats_data['category_counts'].get)

        category_advice = {
            'plastic-bag': "🛍️ 推广可降解购物袋，减少塑料袋使用",
            'plastic-garbage': "♻️ 加强塑料垃圾回收处理",
            'bottle': "🍶 设置饮料瓶回收点",
            'milk-box': "📦 改善包装垃圾处理机制"
        }

        if top_category in category_advice:
            recommendations.append(category_advice[top_category])

        return recommendations


class StatisticsWindow(QDialog):
    """数据统计分析主窗口"""

    def __init__(self, parent=None, table_widget=None):
        super().__init__(parent)
        self.parent = parent
        self.table_widget = table_widget
        self.analyzer = WaterQualityAnalyzer()

        self.setWindowTitle("🌊 AI水面垃圾检测 - 智能数据分析中心")
        self.setWindowIcon(QtGui.QIcon("ui_imgs/icons/目标检测.png"))
        self.resize(2000, 1400)
        self.setMinimumSize(1600, 1000)

        # 收集和处理数据
        self.stats_data = self.collect_statistics_data()

        # 如果没有数据，显示提示
        if not self.stats_data or self.stats_data['total_detections'] == 0:
            self.show_no_data_message()
            return

        # 初始化UI
        self.setup_ui()
        self.apply_theme()
        self.start_animations()

    def collect_statistics_data(self):
        """从表格收集统计数据"""
        if not self.table_widget or self.table_widget.rowCount() == 0:
            return None

        data = {
            'detections': [],
            'category_counts': {},
            'confidence_by_category': {},
            'detection_times': [],
            'processed_images': set(),
            'coordinates': [],
            'total_detections': 0,
            'avg_confidence': 0,
            'avg_detection_time': 0
        }

        # 遍历表格数据
        for row in range(self.table_widget.rowCount()):
            try:
                # 获取表格数据
                path_item = self.table_widget.item(row, 1)
                category_item = self.table_widget.item(row, 2)
                confidence_item = self.table_widget.item(row, 3)
                coords_item = self.table_widget.item(row, 4)

                if not all([path_item, category_item, confidence_item, coords_item]):
                    continue

                # 解析数据
                file_path = path_item.text()
                category = category_item.text()
                confidence_str = confidence_item.text().replace('%', '').strip()
                confidence = float(confidence_str)

                # 解析坐标
                coords_str = coords_item.text().strip('[]')
                coords = [int(x.strip()) for x in coords_str.split(',')]

                # 存储数据
                detection = {
                    'file_path': file_path,
                    'category': category,
                    'confidence': confidence,
                    'coordinates': coords
                }
                data['detections'].append(detection)

                # 统计分类数量
                data['category_counts'][category] = data['category_counts'].get(category, 0) + 1

                # 统计分类置信度
                if category not in data['confidence_by_category']:
                    data['confidence_by_category'][category] = []
                data['confidence_by_category'][category].append(confidence)

                # 记录处理的图片
                data['processed_images'].add(file_path)

                # 记录坐标（用于散点图）
                center_x = (coords[0] + coords[2]) / 2
                center_y = (coords[1] + coords[3]) / 2
                data['coordinates'].append((center_x, center_y, category))

            except Exception as e:
                print(f"数据解析错误: {e}")
                continue

        # 计算统计值
        data['total_detections'] = len(data['detections'])
        data['total_images'] = len(data['processed_images'])

        if data['detections']:
            data['avg_confidence'] = np.mean([d['confidence'] for d in data['detections']])

        # 计算各分类平均置信度
        for category, confidences in data['confidence_by_category'].items():
            data['confidence_by_category'][category] = np.mean(confidences)

        # 模拟检测时间（实际项目中应该记录真实时间）
        data['avg_detection_time'] = np.random.uniform(0.1, 0.5)
        data['detection_times'] = [np.random.uniform(0.05, 0.8) for _ in range(data['total_detections'])]

        return data

    def show_no_data_message(self):
        """显示无数据消息"""
        layout = QVBoxLayout(self)
        layout.setAlignment(Qt.AlignCenter)

        # 创建消息标签
        message_label = QLabel("📊 暂无检测数据")
        message_label.setAlignment(Qt.AlignCenter)
        message_label.setStyleSheet("""
            QLabel {
                font-size: 32px;
                font-weight: bold;
                color: #00e6ff;
                background: transparent;
                padding: 50px;
            }
        """)

        info_label = QLabel("请先进行图片或视频检测，生成数据后再查看统计分析")
        info_label.setAlignment(Qt.AlignCenter)
        info_label.setStyleSheet("""
            QLabel {
                font-size: 16px;
                color: #7ed321;
                background: transparent;
                padding: 20px;
            }
        """)

        layout.addWidget(message_label)
        layout.addWidget(info_label)

        # 应用背景样式
        self.setStyleSheet("""
            QDialog {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #1e2329, stop:1 #2a3441);
            }
        """)

    def setup_ui(self):
        """设置用户界面"""
        main_layout = QVBoxLayout(self)
        main_layout.setContentsMargins(20, 20, 20, 20)
        main_layout.setSpacing(15)

        # 创建标题区域
        self.create_title_section(main_layout)

        # 创建主要内容区域
        self.create_main_content(main_layout)

        # 创建底部控制区域
        self.create_bottom_controls(main_layout)

    def create_title_section(self, parent_layout):
        """创建标题区域"""
        title_frame = QFrame()
        title_frame.setFixedHeight(120)
        title_layout = QHBoxLayout(title_frame)
        title_layout.setContentsMargins(30, 20, 30, 20)

        # 主标题
        title_label = QLabel("🌊 AI智能水质监测分析报告")
        title_label.setObjectName("main_title")

        # 时间戳
        timestamp_label = QLabel(f"📅 生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
        timestamp_label.setObjectName("timestamp")

        # 数据概览
        overview_text = f"📊 共检测 {self.stats_data['total_images']} 张图片，发现 {self.stats_data['total_detections']} 个目标"
        overview_label = QLabel(overview_text)
        overview_label.setObjectName("overview")

        # 布局
        left_layout = QVBoxLayout()
        left_layout.addWidget(title_label)
        left_layout.addWidget(overview_label)
        left_layout.addStretch()

        right_layout = QVBoxLayout()
        right_layout.addStretch()
        right_layout.addWidget(timestamp_label)

        title_layout.addLayout(left_layout, 7)
        title_layout.addLayout(right_layout, 3)

        parent_layout.addWidget(title_frame)

    def create_main_content(self, parent_layout):
        """创建主要内容区域"""
        # 创建标签页
        self.tab_widget = QTabWidget()

        # 添加各个分析标签页
        self.tab_widget.addTab(self.create_overview_tab(), "🏠 总览面板")
        self.tab_widget.addTab(self.create_charts_tab(), "📊 图表分析")
        self.tab_widget.addTab(self.create_spatial_tab(), "🗺️ 空间分析")
        self.tab_widget.addTab(self.create_intelligence_tab(), "🧠 智能评估")
        self.tab_widget.addTab(self.create_report_tab(), "📋 分析报告")

        parent_layout.addWidget(self.tab_widget)

    def create_overview_tab(self):
        """创建总览标签页"""
        widget = QWidget()
        layout = QGridLayout(widget)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(15)

        # 创建统计卡片
        cards_data = [
            ("📊 检测总数", self.stats_data['total_detections'], "#00e6ff"),
            ("📁 图片数量", self.stats_data['total_images'], "#7ed321"),
            ("🎯 平均置信度", f"{self.stats_data['avg_confidence']:.1f}%", "#f5a623"),
            ("⏱️ 平均用时", f"{self.stats_data['avg_detection_time']:.3f}s", "#ff6b6b")
        ]

        for i, (title, value, color) in enumerate(cards_data):
            card = self.create_stat_card(title, str(value), color)
            layout.addWidget(card, 0, i)

        # 创建快速图表预览
        preview_frame = QFrame()
        preview_layout = QHBoxLayout(preview_frame)

        # 分类分布饼图预览
        pie_canvas = self.create_mini_pie_chart()
        preview_layout.addWidget(pie_canvas)

        # 置信度分布柱状图预览
        bar_canvas = self.create_mini_bar_chart()
        preview_layout.addWidget(bar_canvas)

        layout.addWidget(preview_frame, 1, 0, 1, 4)

        return widget

    def create_charts_tab(self):
        """创建图表分析标签页"""
        widget = QWidget()
        layout = QGridLayout(widget)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)

        # 分类数量柱状图
        bar_chart = self.create_category_bar_chart()
        layout.addWidget(bar_chart, 0, 0)

        # 分类分布饼图
        pie_chart = self.create_category_pie_chart()
        layout.addWidget(pie_chart, 0, 1)

        # 置信度分布图
        conf_chart = self.create_confidence_distribution()
        layout.addWidget(conf_chart, 1, 0)

        # 检测时间趋势图
        time_chart = self.create_time_trend_chart()
        layout.addWidget(time_chart, 1, 1)

        return widget

    def create_spatial_tab(self):
        """创建空间分析标签页"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(10, 10, 10, 10)

        # 创建散点图和热力图
        spatial_frame = QFrame()
        spatial_layout = QHBoxLayout(spatial_frame)

        # 垃圾分布散点图
        scatter_chart = self.create_scatter_plot()
        spatial_layout.addWidget(scatter_chart)

        # 分布热力图
        heatmap_chart = self.create_heatmap()
        spatial_layout.addWidget(heatmap_chart)

        layout.addWidget(spatial_frame)

        return widget

    def create_intelligence_tab(self):
        """创建智能评估标签页"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSpacing(20)

        # 计算污染指数
        pollution_index = self.analyzer.calculate_pollution_index(self.stats_data['detections'])
        quality_info = self.analyzer.assess_water_quality(pollution_index)

        # 水质评级展示
        quality_frame = self.create_water_quality_display(pollution_index, quality_info)
        layout.addWidget(quality_frame)

        # 智能分析图表
        analysis_frame = QFrame()
        analysis_layout = QHBoxLayout(analysis_frame)

        # 污染贡献度图
        contribution_chart = self.create_pollution_contribution_chart()
        analysis_layout.addWidget(contribution_chart)

        # 风险评估雷达图
        radar_chart = self.create_risk_radar_chart()
        analysis_layout.addWidget(radar_chart)

        layout.addWidget(analysis_frame)

        return widget

    def create_report_tab(self):
        """创建分析报告标签页"""
        widget = QWidget()
        layout = QVBoxLayout(widget)
        layout.setContentsMargins(20, 20, 20, 20)

        # 生成分析报告
        pollution_index = self.analyzer.calculate_pollution_index(self.stats_data['detections'])
        quality_info = self.analyzer.assess_water_quality(pollution_index)
        report = self.analyzer.generate_analysis_report(self.stats_data, pollution_index, quality_info)

        # 创建报告文本
        report_text = self.format_analysis_report(report)

        # 创建文本展示区域
        report_display = QTextEdit()
        report_display.setHtml(report_text)
        report_display.setReadOnly(True)

        layout.addWidget(report_display)

        # 添加导出按钮
        export_btn = QPushButton("📄 导出报告")
        export_btn.clicked.connect(lambda: self.export_report(report))
        layout.addWidget(export_btn)

        return widget

    def create_stat_card(self, title, value, color):
        """创建统计卡片"""
        card = QFrame()
        card.setFixedHeight(120)
        card.setObjectName("stat_card")

        layout = QVBoxLayout(card)
        layout.setContentsMargins(20, 15, 20, 15)
        layout.setAlignment(Qt.AlignCenter)

        # 标题
        title_label = QLabel(title)
        title_label.setAlignment(Qt.AlignCenter)
        title_label.setObjectName("card_title")

        # 数值
        value_label = QLabel(value)
        value_label.setAlignment(Qt.AlignCenter)
        value_label.setObjectName("card_value")
        value_label.setStyleSheet(f"color: {color}; font-size: 28px; font-weight: bold;")

        layout.addWidget(title_label)
        layout.addWidget(value_label)

        return card

    def create_mini_pie_chart(self):
        """创建迷你饼图"""
        canvas = AnimatedCanvas(width=6, height=4)
        ax = canvas.fig.add_subplot(111)

        categories = list(self.stats_data['category_counts'].keys())
        counts = list(self.stats_data['category_counts'].values())

        # 创建饼图
        colors = sns.color_palette("husl", len(categories))
        wedges, texts, autotexts = ax.pie(counts, labels=categories, colors=colors,
                                          autopct='%1.1f%%', startangle=90)

        ax.set_title(safe_text.safe_title('🗂️ 分类分布概览'), fontsize=14, color='white', pad=20)

        # 美化文本
        for text in texts + autotexts:
            text.set_color('white')
            text.set_fontsize(10)

        canvas.fig.tight_layout()
        return canvas

    def create_mini_bar_chart(self):
        """创建迷你柱状图"""
        canvas = AnimatedCanvas(width=6, height=4)
        ax = canvas.fig.add_subplot(111)

        categories = list(self.stats_data['confidence_by_category'].keys())
        confidences = list(self.stats_data['confidence_by_category'].values())

        # 创建柱状图
        bars = ax.bar(categories, confidences, color=sns.color_palette("viridis", len(categories)))

        # 添加数值标签
        for bar, conf in zip(bars, confidences):
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width() / 2., height + 1,
                    f'{conf:.1f}%', ha='center', va='bottom', color='white', fontsize=9)

        ax.set_title(safe_text.safe_title('📊 平均置信度分布'), fontsize=14, color='white', pad=20)
        ax.set_ylabel('置信度 (%)', color='white')
        ax.tick_params(colors='white', rotation=45)

        canvas.fig.tight_layout()
        return canvas

    def create_category_bar_chart(self):
        plt.rcParams['font.sans-serif'] = [custom_font.get_name()]
        """创建分类数量柱状图"""
        canvas = AnimatedCanvas(width=8, height=6)
        ax = canvas.fig.add_subplot(111)

        categories = list(self.stats_data['category_counts'].keys())
        counts = list(self.stats_data['category_counts'].values())

        # 创建渐变色柱状图
        colors = plt.cm.plasma(np.linspace(0, 1, len(categories)))
        bars = ax.bar(categories, counts, color=colors, alpha=0.8, edgecolor='white', linewidth=2)

        # 添加数值标签
        for bar, count in zip(bars, counts):
            height = bar.get_height()
            ax.text(bar.get_x() + bar.get_width() / 2., height + 0.5,
                    str(count), ha='center', va='bottom', color='white', fontsize=12, fontweight='bold')

        # 使用安全标题
        # ax.set_title(safe_text.safe_title('📊 垃圾分类检测数量统计'), fontsize=16, color='white', fontweight='bold',pad=20)
        ax.set_title('垃圾分类检测数量统计', fontsize=16, color='white', fontweight='bold',pad=20)
        ax.set_xlabel('垃圾类别', fontsize=12, color='white')
        ax.set_ylabel('检测数量', fontsize=12, color='white')
        ax.tick_params(colors='white', rotation=45)
        ax.grid(True, alpha=0.3, color='white')
        ax.set_facecolor('#2a3441')

        # 设置y轴从0开始
        ax.set_ylim(0, max(counts) * 1.2)

        canvas.fig.tight_layout()
        return canvas

    def create_category_pie_chart(self):
        """创建分类分布饼图"""
        canvas = AnimatedCanvas(width=8, height=6)
        ax = canvas.fig.add_subplot(111)

        categories = list(self.stats_data['category_counts'].keys())
        counts = list(self.stats_data['category_counts'].values())

        # 创建饼图
        colors = plt.cm.Set3(np.linspace(0, 1, len(categories)))
        wedges, texts, autotexts = ax.pie(counts, labels=categories, colors=colors,
                                          autopct='%1.1f%%', startangle=90,
                                          explode=[0.05] * len(categories),
                                          shadow=True, textprops={'color': 'white', 'fontsize': 11})

        # 美化文本
        for autotext in autotexts:
            autotext.set_color('black')
            autotext.set_fontweight('bold')
            autotext.set_fontsize(10)

        ax.set_title(safe_text.safe_title('🥧 垃圾分类分布比例'), fontsize=16, color='white', fontweight='bold', pad=20)

        canvas.fig.tight_layout()
        return canvas

    def create_confidence_distribution(self):
        """创建置信度分布图"""
        canvas = AnimatedCanvas(width=8, height=6)
        ax = canvas.fig.add_subplot(111)

        # 收集所有置信度数据
        all_confidences = [d['confidence'] for d in self.stats_data['detections']]

        # 创建直方图
        n, bins, patches = ax.hist(all_confidences, bins=20, color='skyblue',
                                   alpha=0.7, edgecolor='white', linewidth=1.5)

        # 着色渐变
        for i, patch in enumerate(patches):
            patch.set_facecolor(plt.cm.viridis(i / len(patches)))

        # 添加统计线
        mean_conf = np.mean(all_confidences)
        ax.axvline(mean_conf, color='red', linestyle='--', linewidth=2,
                   label=f'平均值: {mean_conf:.1f}%')

        # 美化图表
        ax.set_title(safe_text.safe_title('📈 检测置信度分布'), fontsize=16, color='white', fontweight='bold', pad=20)
        ax.set_xlabel('置信度 (%)', fontsize=12, color='white')
        ax.set_ylabel('频次', fontsize=12, color='white')
        ax.tick_params(colors='white')
        ax.grid(True, alpha=0.3, color='white')
        ax.legend(loc='upper left', facecolor='#2a3441',labelcolor='white', edgecolor='white')
        ax.set_facecolor('#2a3441')

        canvas.fig.tight_layout()
        return canvas

    def create_time_trend_chart(self):
        """创建检测时间趋势图"""
        canvas = AnimatedCanvas(width=8, height=6)
        ax = canvas.fig.add_subplot(111)

        detection_times = self.stats_data['detection_times']
        x_values = range(len(detection_times))

        # 创建折线图
        line = ax.plot(x_values, detection_times, color='#00ff88', linewidth=3,
                       marker='o', markersize=6, markerfacecolor='white',
                       markeredgecolor='#00ff88', markeredgewidth=2, alpha=0.8)[0]

        # 添加趋势线
        z = np.polyfit(x_values, detection_times, 1)
        p = np.poly1d(z)
        ax.plot(x_values, p(x_values), "r--", alpha=0.8, linewidth=2, label='趋势线')

        # 填充区域
        ax.fill_between(x_values, detection_times, alpha=0.3, color='#00ff88')

        # 美化图表
        ax.set_title(safe_text.safe_title('⏱️ 检测时间变化趋势'), fontsize=16, color='white', fontweight='bold', pad=20)
        ax.set_xlabel('检测序号', fontsize=12, color='white')
        ax.set_ylabel('检测时间 (秒)', fontsize=12, color='white')
        ax.tick_params(colors='white')
        ax.grid(True, alpha=0.3, color='white')
        ax.legend(facecolor='#2a3441',labelcolor='white', edgecolor='white')
        ax.set_facecolor('#2a3441')

        canvas.fig.tight_layout()
        return canvas

    def create_scatter_plot(self):
        """创建垃圾分布散点图"""
        canvas = AnimatedCanvas(width=9, height=7)
        ax = canvas.fig.add_subplot(111)

        # 准备数据
        coordinates = self.stats_data['coordinates']
        categories = list(set([coord[2] for coord in coordinates]))
        colors = plt.cm.tab10(np.linspace(0, 1, len(categories)))

        # 为每个类别创建散点
        for i, category in enumerate(categories):
            category_coords = [coord for coord in coordinates if coord[2] == category]
            if category_coords:
                x_coords = [coord[0] for coord in category_coords]
                y_coords = [coord[1] for coord in category_coords]
                ax.scatter(x_coords, y_coords, c=[colors[i]], label=category,
                           s=80, alpha=0.7, edgecolors='white', linewidth=1.5)

        # 美化图表
        ax.set_title(safe_text.safe_title('🗺️ 垃圾空间分布散点图'), fontsize=16, color='white', fontweight='bold',
                     pad=20)

        ax.set_xlabel('X坐标', fontsize=12, color='white')
        ax.set_ylabel('Y坐标', fontsize=12, color='white')
        ax.tick_params(colors='white')
        ax.grid(True, alpha=0.3, color='white')
        ax.legend(bbox_to_anchor=(1.05, 1), loc='upper left', facecolor='#2a3441',labelcolor='white', edgecolor='white')
        ax.set_facecolor('#2a3441')

        # 反转Y轴（图像坐标系）
        ax.invert_yaxis()

        canvas.fig.tight_layout()
        return canvas

    def create_heatmap(self):
        """创建分布热力图"""
        canvas = AnimatedCanvas(width=9, height=7)
        ax = canvas.fig.add_subplot(111)

        # 创建热力图数据
        coordinates = self.stats_data['coordinates']
        if coordinates:
            x_coords = [coord[0] for coord in coordinates]
            y_coords = [coord[1] for coord in coordinates]

            # 创建2D直方图
            heatmap, xedges, yedges = np.histogram2d(x_coords, y_coords, bins=15)

            # 绘制热力图
            im = ax.imshow(heatmap.T, origin='lower', cmap='hot', alpha=0.8,
                           extent=[min(x_coords), max(x_coords), min(y_coords), max(y_coords)])

            # 添加颜色条
            cbar = canvas.fig.colorbar(im, ax=ax, shrink=0.8)
            cbar.set_label('密度', color='white', fontsize=12)
            cbar.ax.tick_params(colors='white')

        # 美化图表
        ax.set_title(safe_text.safe_title('🔥 垃圾密度热力图'), fontsize=16, color='white', fontweight='bold', pad=20)
        ax.set_xlabel('X坐标', fontsize=12, color='white')
        ax.set_ylabel('Y坐标', fontsize=12, color='white')
        ax.tick_params(colors='white')
        ax.set_facecolor('#2a3441')

        canvas.fig.tight_layout()
        return canvas

    def create_water_quality_display(self, pollution_index, quality_info):
        """创建水质评级显示"""
        frame = QFrame()
        frame.setFixedHeight(200)
        layout = QHBoxLayout(frame)
        layout.setContentsMargins(30, 20, 30, 20)

        # 左侧评级显示
        grade_widget = QWidget()
        grade_layout = QVBoxLayout(grade_widget)
        grade_layout.setAlignment(Qt.AlignCenter)

        # 等级标签
        grade_label = QLabel(f"水质等级: {quality_info['level']}")
        grade_label.setAlignment(Qt.AlignCenter)
        grade_label.setStyleSheet(f"""
            QLabel {{
                font-size: 36px;
                font-weight: bold;
                color: {quality_info['color']};
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 rgba(0,0,0,0.3), stop:1 rgba(255,255,255,0.1));
                border: 3px solid {quality_info['color']};
                border-radius: 15px;
                padding: 20px;
                margin: 10px;
            }}
        """)

        # 描述标签
        desc_label = QLabel(quality_info['desc'])
        desc_label.setAlignment(Qt.AlignCenter)
        desc_label.setStyleSheet(f"""
            QLabel {{
                font-size: 20px;
                color: {quality_info['color']};
                font-weight: bold;
            }}
        """)

        grade_layout.addWidget(grade_label)
        grade_layout.addWidget(desc_label)

        # 右侧污染指数和建议
        info_widget = QWidget()
        info_layout = QVBoxLayout(info_widget)

        # 污染指数
        index_label = QLabel(f"污染指数: {pollution_index:.3f}")
        index_label.setStyleSheet("""
            QLabel {
                font-size: 18px;
                color: #00e6ff;
                font-weight: bold;
                margin-bottom: 10px;
            }
        """)

        # 建议
        advice_label = QLabel(quality_info['advice'])
        advice_label.setWordWrap(True)
        advice_label.setStyleSheet("""
            QLabel {
                font-size: 16px;
                color: #ffffff;
                background-color: rgba(0, 0, 0, 0.3);
                border-radius: 10px;
                padding: 15px;
                border: 1px solid #00e6ff;
            }
        """)

        info_layout.addWidget(index_label)
        info_layout.addWidget(advice_label)
        info_layout.addStretch()

        layout.addWidget(grade_widget, 4)
        layout.addWidget(info_widget, 6)

        return frame

    def create_pollution_contribution_chart(self):
        """创建污染贡献度图表"""
        canvas = AnimatedCanvas(width=8, height=6)
        ax = canvas.fig.add_subplot(111)

        # 计算各类型污染贡献
        contributions = {}
        for detection in self.stats_data['detections']:
            category = detection['category']
            confidence = detection['confidence'] / 100
            weight = self.analyzer.pollution_weights.get(category, 0.5)
            contribution = weight * confidence

            if category not in contributions:
                contributions[category] = []
            contributions[category].append(contribution)

        # 计算平均贡献度
        avg_contributions = {cat: np.mean(vals) for cat, vals in contributions.items()}

        # 创建横向柱状图
        categories = list(avg_contributions.keys())
        values = list(avg_contributions.values())

        colors = plt.cm.Reds(np.linspace(0.3, 1, len(categories)))
        bars = ax.barh(categories, values, color=colors, alpha=0.8, edgecolor='white', linewidth=2)

        # 添加数值标签
        for bar, value in zip(bars, values):
            width = bar.get_width()
            ax.text(width + 0.01, bar.get_y() + bar.get_height() / 2,
                    f'{value:.3f}', ha='left', va='center', color='white', fontweight='bold')

        ax.set_title(safe_text.safe_title('🏭 各类型污染贡献度分析'), fontsize=16, color='white', fontweight='bold', pad=20)
        ax.set_xlabel('污染贡献度', fontsize=12, color='white')
        ax.tick_params(colors='white')
        ax.grid(True, alpha=0.3, color='white', axis='x')
        ax.set_facecolor('#2a3441')

        canvas.fig.tight_layout()
        return canvas

    def create_risk_radar_chart(self):
        """创建风险评估雷达图"""
        canvas = AnimatedCanvas(width=8, height=6)
        ax = canvas.fig.add_subplot(111, projection='polar')

        # 定义评估维度
        dimensions = ['塑料污染', '检测密度', '置信度', '空间分布', '处理紧急度']

        # 计算各维度得分（0-100）
        plastic_pollution = sum(1 for d in self.stats_data['detections']
                                if d['category'] in ['plastic-bag', 'plastic-garbage', 'bottle']) / len(
            self.stats_data['detections']) * 100

        detection_density = min(self.stats_data['total_detections'] / self.stats_data['total_images'] * 20, 100)
        avg_confidence = self.stats_data['avg_confidence']
        spatial_spread = min(len(set(d['file_path'] for d in self.stats_data['detections'])) * 10, 100)
        urgency = plastic_pollution * 0.6 + detection_density * 0.4

        scores = [plastic_pollution, detection_density, avg_confidence, spatial_spread, urgency]

        # 创建雷达图
        angles = np.linspace(0, 2 * np.pi, len(dimensions), endpoint=False)
        scores_plot = scores + [scores[0]]  # 闭合图形
        angles_plot = np.concatenate([angles, [angles[0]]])

        # 绘制雷达图
        line = ax.plot(angles_plot, scores_plot, 'o-', linewidth=3, color='#00ff88', markersize=8)
        ax.fill(angles_plot, scores_plot, alpha=0.25, color='#00ff88')

        # 设置标签
        ax.set_thetagrids(angles * 180 / np.pi, dimensions, color='white', fontsize=11)
        ax.set_ylim(0, 100)
        ax.set_yticks([20, 40, 60, 80, 100])
        ax.set_yticklabels(['20', '40', '60', '80', '100'], color='white', fontsize=9)
        ax.grid(True, color='white', alpha=0.3)
        ax.set_facecolor('#2a3441')

        ax.set_title(safe_text.safe_title('⚡ 环境风险评估雷达图'), fontsize=16, color='white', fontweight='bold', pad=30)

        canvas.fig.tight_layout()
        return canvas

    def format_analysis_report(self, report):
        """格式化分析报告"""
        html_content = f"""
        <html>
        <head>
            <style>
                body {{ 
                    background-color: #1e2329; 
                    color: white; 
                    font-family: 'Microsoft YaHei', Arial, sans-serif;
                    line-height: 1.6;
                    padding: 20px;
                }}
                h1 {{ color: #00e6ff; font-size: 24px; text-align: center; margin-bottom: 30px; }}
                h2 {{ color: #7ed321; font-size: 18px; margin-top: 25px; margin-bottom: 15px; }}
                h3 {{ color: #f5a623; font-size: 16px; margin-top: 20px; margin-bottom: 10px; }}
                .highlight {{ 
                    background-color: {report['overall_assessment']['color']}; 
                    color: black; 
                    padding: 5px 10px; 
                    border-radius: 5px; 
                    font-weight: bold; 
                }}
                .metric {{ 
                    background-color: #2a3441; 
                    padding: 10px; 
                    margin: 10px 0; 
                    border-left: 4px solid #00e6ff; 
                    border-radius: 5px; 
                }}
                .recommendation {{ 
                    background-color: #2a3441; 
                    padding: 8px 12px; 
                    margin: 5px 0; 
                    border-left: 3px solid #7ed321; 
                    border-radius: 3px; 
                }}
                .finding {{ 
                    background-color: #2a3441; 
                    padding: 8px 12px; 
                    margin: 5px 0; 
                    border-left: 3px solid #f5a623; 
                    border-radius: 3px; 
                }}
                ul {{ padding-left: 20px; }}
                li {{ margin-bottom: 8px; }}
            </style>
        </head>
        <body>
            <h1>🌊 AI智能水质检测分析报告</h1>

            <div class="metric">
                <strong>📅 生成时间:</strong> {report['timestamp']}<br>
                <strong>🎯 检测总数:</strong> {self.stats_data['total_detections']} 个目标<br>
                <strong>📁 图片数量:</strong> {self.stats_data['total_images']} 张<br>
                <strong>📊 平均置信度:</strong> {self.stats_data['avg_confidence']:.1f}%<br>
                <strong>⏱️ 平均检测时间:</strong> {self.stats_data['avg_detection_time']:.3f}s
            </div>

            <h2>🏆 水质评估结果</h2>
            <div class="metric">
                <strong>水质等级:</strong> <span class="highlight">{report['overall_assessment']['level']} - {report['overall_assessment']['desc']}</span><br>
                <strong>污染指数:</strong> {report['pollution_index']:.3f}<br>
                <strong>评估建议:</strong> {report['overall_assessment']['advice']}
            </div>

            <h2>🔍 关键发现</h2>
            <ul>
        """

        for finding in report['key_findings']:
            html_content += f'<li class="finding">{finding}</li>'

        html_content += """
            </ul>

            <h2>📋 改善建议</h2>
            <ul>
        """

        for recommendation in report['recommendations']:
            html_content += f'<li class="recommendation">{recommendation}</li>'

        html_content += """
            </ul>

            <h2>📊 详细统计数据</h2>
        """

        for category, count in self.stats_data['category_counts'].items():
            percentage = (count / self.stats_data['total_detections']) * 100
            avg_conf = self.stats_data['confidence_by_category'][category]
            html_content += f"""
            <div class="metric">
                <strong>{category}:</strong> {count} 个 ({percentage:.1f}%) | 
                平均置信度: {avg_conf:.1f}%
            </div>
            """

        html_content += """
            <h3>💡 系统说明</h3>
            <div class="metric">
                本报告基于YOLOv8深度学习模型的检测结果生成，通过多维度数据分析和智能算法评估水质状况。
                污染指数综合考虑垃圾类型、数量密度、置信度等因素，为环境保护提供科学决策支持。
            </div>

            </body>
        </html>
        """

        return html_content

    def export_report(self, report):
        """导出分析报告"""
        try:
            from PyQt5.QtWidgets import QFileDialog

            file_path, _ = QFileDialog.getSaveFileName(
                self, "保存分析报告",
                f"水质分析报告_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html",
                "HTML files (*.html)"
            )

            if file_path:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write(self.format_analysis_report(report))

                from PyQt5.QtWidgets import QMessageBox
                QMessageBox.information(self, "成功", f"报告已保存至:\n{file_path}")

        except Exception as e:
            from PyQt5.QtWidgets import QMessageBox
            QMessageBox.warning(self, "错误", f"报告导出失败:\n{str(e)}")

    def create_bottom_controls(self, parent_layout):
        """创建底部控制区域"""
        controls_frame = QFrame()
        controls_frame.setFixedHeight(70)
        controls_layout = QHBoxLayout(controls_frame)
        controls_layout.setContentsMargins(20, 10, 20, 10)

        # 刷新按钮
        refresh_btn = QPushButton("🔄 刷新数据")
        refresh_btn.setFixedHeight(50)
        refresh_btn.clicked.connect(self.refresh_data)

        # 关闭按钮
        close_btn = QPushButton("❌ 关闭窗口")
        close_btn.setFixedHeight(50)
        close_btn.clicked.connect(self.close)

        controls_layout.addStretch()
        controls_layout.addWidget(refresh_btn)
        controls_layout.addWidget(close_btn)

        parent_layout.addWidget(controls_frame)

    def refresh_data(self):
        """刷新数据"""
        # 重新收集数据
        new_stats_data = self.collect_statistics_data()
        if new_stats_data and new_stats_data['total_detections'] > 0:
            self.stats_data = new_stats_data
            # 重新创建所有图表
            self.recreate_all_charts()

    def recreate_all_charts(self):
        """重新创建所有图表"""
        # 这里可以添加重新创建图表的逻辑
        pass

    def apply_theme(self):
        """应用主题样式"""
        self.setStyleSheet("""
            QDialog {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #1e2329, stop:0.3 #2a3441, stop:0.7 #364153, stop:1 #4a5568);
            }

            QTabWidget::pane {
                border: 2px solid #00e6ff;
                border-radius: 12px;
                background-color: rgba(30, 35, 41, 0.9);
            }

            QTabWidget::tab-bar {
                alignment: center;
            }

            QTabBar::tab {
                background-color: rgba(42, 52, 65, 0.8);
                color: white;
                padding: 12px 20px;
                margin: 2px;
                border-radius: 8px;
                font-size: 14px;
                font-weight: bold;
                min-width: 120px;
            }

            QTabBar::tab:selected {
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1, 
                    stop:0 #00e6ff, stop:1 #0099cc);
                color: black;
            }

            QTabBar::tab:hover {
                background-color: rgba(0, 230, 255, 0.3);
            }

            QFrame#stat_card {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 rgba(42, 52, 65, 0.8), stop:1 rgba(58, 73, 88, 0.8));
                border: 2px solid #00e6ff;
                border-radius: 12px;
            }

            QLabel#card_title {
                color: #00e6ff;
                font-size: 14px;
                font-weight: bold;
            }

            QLabel#main_title {
                font-size: 28px;
                font-weight: bold;
                color: #00e6ff;
            }

            QLabel#timestamp {
                font-size: 14px;
                color: #7ed321;
            }

            QLabel#overview {
                font-size: 16px;
                color: #f5a623;
            }

            QPushButton {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #00aaff, stop:1 #00e6ff);
                border: none;
                border-radius: 8px;
                color: white;
                font-size: 14px;
                font-weight: bold;
                padding: 10px 20px;
            }

            QPushButton:hover {
                background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                    stop:0 #00e6ff, stop:1 #33ffff);
                transform: translateY(-2px);
            }

            QPushButton:pressed {
                background: #0099cc;
                transform: translateY(1px);
            }

            QTextEdit {
                background-color: rgba(30, 35, 41, 0.9);
                border: 2px solid #00e6ff;
                border-radius: 10px;
                color: white;
                font-size: 13px;
                padding: 10px;
            }
        """)

    def start_animations(self):
        """启动动画效果"""
        # 窗口淡入动画
        self.setWindowOpacity(0.0)
        self.animation = QPropertyAnimation(self, b"windowOpacity")
        self.animation.setDuration(800)
        self.animation.setStartValue(0.0)
        self.animation.setEndValue(1.0)
        self.animation.start()

        # 添加标题动画
        self.title_timer = QTimer()
        self.title_timer.timeout.connect(self.animate_title)
        self.title_timer.start(2000)

    def animate_title(self):
        """标题动画效果"""
        # 可以添加标题闪烁或颜色变化效果
        pass


class AdvancedVisualizationWidget(QWidget):
    """高级可视化组件"""

    def __init__(self, stats_data, parent=None):
        super().__init__(parent)
        self.stats_data = stats_data
        self.setup_ui()

    def setup_ui(self):
        """设置高级可视化界面"""
        layout = QVBoxLayout(self)

        # 创建交互式图表控制面板
        control_panel = self.create_control_panel()
        layout.addWidget(control_panel)

        # 创建可切换的高级图表区域
        self.chart_stack = QtWidgets.QStackedWidget()

        # 添加不同类型的高级图表
        self.chart_stack.addWidget(self.create_3d_scatter_plot())
        self.chart_stack.addWidget(self.create_correlation_matrix())
        self.chart_stack.addWidget(self.create_time_series_analysis())
        self.chart_stack.addWidget(self.create_clustering_visualization())

        layout.addWidget(self.chart_stack)

    def create_control_panel(self):
        """创建图表控制面板"""
        panel = QFrame()
        panel.setFixedHeight(80)
        layout = QHBoxLayout(panel)  # 修复：QHboxLayout -> QHBoxLayout

        # 图表类型选择
        chart_combo = QtWidgets.QComboBox()
        chart_combo.addItems([
            "3D Scatter Analysis", "Correlation Matrix",
            "Time Series Analysis", "Clustering Visualization"
        ])
        chart_combo.currentIndexChanged.connect(self.chart_stack.setCurrentIndex)

        # 参数调节滑块
        param_slider = QtWidgets.QSlider(Qt.Horizontal)
        param_slider.setRange(1, 100)
        param_slider.setValue(50)

        layout.addWidget(QLabel("Chart Type:"))
        layout.addWidget(chart_combo)
        layout.addWidget(QLabel("Parameter:"))
        layout.addWidget(param_slider)
        layout.addStretch()

        return panel

    def create_3d_scatter_plot(self):
        """创建3D散点图"""
        from mpl_toolkits.mplot3d import Axes3D

        canvas = AnimatedCanvas(width=10, height=8)
        ax = canvas.fig.add_subplot(111, projection='3d')

        # 准备3D数据
        coordinates = self.stats_data['coordinates']
        if coordinates:
            x_coords = [coord[0] for coord in coordinates]
            y_coords = [coord[1] for coord in coordinates]
            z_coords = [self.stats_data['detections'][i]['confidence']
                        for i in range(len(coordinates))]

            categories = [coord[2] for coord in coordinates]
            unique_categories = list(set(categories))
            colors = plt.cm.tab10(np.linspace(0, 1, len(unique_categories)))

            for i, category in enumerate(unique_categories):
                mask = [cat == category for cat in categories]
                x_cat = [x for j, x in enumerate(x_coords) if mask[j]]
                y_cat = [y for j, y in enumerate(y_coords) if mask[j]]
                z_cat = [z for j, z in enumerate(z_coords) if mask[j]]

                ax.scatter(x_cat, y_cat, z_cat, c=[colors[i]],
                           label=category, s=60, alpha=0.7)

        ax.set_xlabel('X坐标', color='white')
        ax.set_ylabel('Y坐标', color='white')
        ax.set_zlabel('置信度', color='white')
        ax.set_title(safe_text.safe_title('🎯 3D垃圾分布与置信度分析'), color='white', fontsize=16, pad=20)
        ax.legend()

        # 设置背景色
        ax.xaxis.pane.fill = False
        ax.yaxis.pane.fill = False
        ax.zaxis.pane.fill = False
        ax.xaxis.pane.set_edgecolor('white')
        ax.yaxis.pane.set_edgecolor('white')
        ax.zaxis.pane.set_edgecolor('white')

        canvas.fig.tight_layout()
        return canvas

    def create_correlation_matrix(self):
        """创建相关性矩阵热力图"""
        canvas = AnimatedCanvas(width=10, height=8)
        ax = canvas.fig.add_subplot(111)

        # 构建相关性数据
        categories = list(self.stats_data['category_counts'].keys())
        n_categories = len(categories)

        # 模拟相关性矩阵（实际项目中应基于真实数据计算）
        correlation_matrix = np.random.rand(n_categories, n_categories)
        correlation_matrix = (correlation_matrix + correlation_matrix.T) / 2
        np.fill_diagonal(correlation_matrix, 1.0)

        # 创建热力图
        im = ax.imshow(correlation_matrix, cmap='RdYlBu_r', aspect='auto')

        # 设置标签
        ax.set_xticks(range(n_categories))
        ax.set_yticks(range(n_categories))
        ax.set_xticklabels(categories, rotation=45, ha='right', color='white')
        ax.set_yticklabels(categories, color='white')

        # 添加数值标注
        for i in range(n_categories):
            for j in range(n_categories):
                text = ax.text(j, i, f'{correlation_matrix[i, j]:.2f}',
                               ha="center", va="center", color="black", fontweight='bold')

        # 添加颜色条
        cbar = canvas.fig.colorbar(im, ax=ax, shrink=0.8)
        cbar.set_label('相关性系数', color='white')
        cbar.ax.tick_params(colors='white')

        ax.set_title(safe_text.safe_title('🔗 垃圾类型相关性分析'), color='white', fontsize=16, pad=20)
        canvas.fig.tight_layout()
        return canvas

    def create_time_series_analysis(self):
        """创建时间序列分析图"""
        canvas = AnimatedCanvas(width=10, height=8)
        fig = canvas.fig

        # 创建子图
        gs = fig.add_gridspec(2, 2, hspace=0.3, wspace=0.3)

        # 检测数量时间序列
        ax1 = fig.add_subplot(gs[0, :])
        detection_counts = np.random.poisson(5, 30)  # 模拟30天的检测数据
        days = range(1, 31)

        ax1.plot(days, detection_counts, marker='o', linewidth=2, markersize=6,
                 color='#00ff88', markerfacecolor='white', markeredgecolor='#00ff88')
        ax1.fill_between(days, detection_counts, alpha=0.3, color='#00ff88')
        ax1.set_title('📈 检测数量时间趋势', color='white', fontsize=14)
        ax1.set_xlabel('天数', color='white')
        ax1.set_ylabel('检测数量', color='white')
        ax1.tick_params(colors='white')
        ax1.grid(True, alpha=0.3, color='white')
        ax1.set_facecolor('#2a3441')

        # 置信度变化
        ax2 = fig.add_subplot(gs[1, 0])
        confidence_trend = np.random.normal(75, 10, 30)
        ax2.plot(days, confidence_trend, color='#f5a623', linewidth=2)
        ax2.set_title('🎯 置信度变化', color='white', fontsize=12)
        ax2.set_xlabel('天数', color='white')
        ax2.set_ylabel('置信度(%)', color='white')
        ax2.tick_params(colors='white')
        ax2.grid(True, alpha=0.3, color='white')
        ax2.set_facecolor('#2a3441')

        # 处理时间变化
        ax3 = fig.add_subplot(gs[1, 1])
        processing_time = np.random.exponential(0.3, 30)
        ax3.plot(days, processing_time, color='#ff6b6b', linewidth=2)
        ax3.set_title('⏱️ 处理时间变化', color='white', fontsize=12)
        ax3.set_xlabel('天数', color='white')
        ax3.set_ylabel('时间(s)', color='white')
        ax3.tick_params(colors='white')
        ax3.grid(True, alpha=0.3, color='white')
        ax3.set_facecolor('#2a3441')

        return canvas

    def create_clustering_visualization(self):
        """创建聚类可视化"""
        canvas = AnimatedCanvas(width=10, height=8)
        ax = canvas.fig.add_subplot(111)

        # 准备聚类数据
        coordinates = self.stats_data['coordinates']
        if coordinates and len(coordinates) > 3:
            from sklearn.cluster import KMeans

            # 提取坐标数据
            X = np.array([[coord[0], coord[1]] for coord in coordinates])

            # 执行K-means聚类
            n_clusters = min(4, len(set([coord[2] for coord in coordinates])))
            kmeans = KMeans(n_clusters=n_clusters, random_state=42)
            cluster_labels = kmeans.fit_predict(X)

            # 绘制聚类结果
            colors = plt.cm.Set1(np.linspace(0, 1, n_clusters))
            for i in range(n_clusters):
                mask = cluster_labels == i
                ax.scatter(X[mask, 0], X[mask, 1], c=[colors[i]],
                           label=f'聚类 {i + 1}', s=60, alpha=0.7, edgecolors='white')

            # 绘制聚类中心
            centers = kmeans.cluster_centers_
            ax.scatter(centers[:, 0], centers[:, 1], c='red', marker='x',
                       s=200, linewidths=3, label='聚类中心')

            ax.set_xlabel('X坐标', color='white')
            ax.set_ylabel('Y坐标', color='white')
            ax.set_title(safe_text.safe_title('🎨 垃圾分布聚类分析'), color='white', fontsize=16, pad=20)
            ax.legend(facecolor='#2a3441', edgecolor='white',labelcolor='white')
            ax.tick_params(colors='white')
            ax.grid(True, alpha=0.3, color='white')
            ax.set_facecolor('#2a3441')
        else:
            ax.text(0.5, 0.5, '数据不足，无法进行聚类分析',
                    transform=ax.transAxes, ha='center', va='center',
                    color='white', fontsize=14)
            ax.set_facecolor('#2a3441')

        canvas.fig.tight_layout()
        return canvas


class ExportManager:
    """数据导出管理器"""

    @staticmethod
    def export_to_excel(stats_data, file_path):
        """导出数据到Excel"""
        try:
            import pandas as pd

            # 创建多个工作表
            with pd.ExcelWriter(file_path, engine='openpyxl') as writer:
                # 基础统计数据
                basic_stats = pd.DataFrame({
                    '指标': ['检测总数', '图片数量', '平均置信度', '平均检测时间'],
                    '数值': [
                        stats_data['total_detections'],
                        stats_data['total_images'],
                        f"{stats_data['avg_confidence']:.2f}%",
                        f"{stats_data['avg_detection_time']:.3f}s"
                    ]
                })
                basic_stats.to_excel(writer, sheet_name='基础统计', index=False)

                # 分类统计
                category_stats = pd.DataFrame({
                    '类别': list(stats_data['category_counts'].keys()),
                    '数量': list(stats_data['category_counts'].values()),
                    '平均置信度': [f"{conf:.2f}%" for conf in stats_data['confidence_by_category'].values()]
                })
                category_stats.to_excel(writer, sheet_name='分类统计', index=False)

                # 详细检测数据
                detailed_data = pd.DataFrame(stats_data['detections'])
                detailed_data.to_excel(writer, sheet_name='详细数据', index=False)

            return True
        except Exception as e:
            print(f"Excel导出失败: {e}")
            return False

    @staticmethod
    def export_to_json(stats_data, file_path):
        """导出数据到JSON"""
        try:
            # 处理不可序列化的数据
            export_data = {
                'timestamp': datetime.now().isoformat(),
                'basic_stats': {
                    'total_detections': stats_data['total_detections'],
                    'total_images': stats_data['total_images'],
                    'avg_confidence': float(stats_data['avg_confidence']),
                    'avg_detection_time': float(stats_data['avg_detection_time'])
                },
                'category_counts': stats_data['category_counts'],
                'confidence_by_category': {k: float(v) for k, v in stats_data['confidence_by_category'].items()},
                'detections': [
                    {
                        'file_path': d['file_path'],
                        'category': d['category'],
                        'confidence': float(d['confidence']),
                        'coordinates': d['coordinates']
                    } for d in stats_data['detections']
                ]
            }

            with open(file_path, 'w', encoding='utf-8') as f:
                json.dump(export_data, f, ensure_ascii=False, indent=2)

            return True
        except Exception as e:
            print(f"JSON导出失败: {e}")
            return False


# 在StatisticsWindow类中添加导出功能
def add_export_functionality(self):
    """添加导出功能到底部控制区域"""
    # 在create_bottom_controls方法中添加导出按钮
    export_excel_btn = QPushButton("📊 导出Excel")
    export_excel_btn.clicked.connect(self.export_to_excel)

    export_json_btn = QPushButton("📄 导出JSON")
    export_json_btn.clicked.connect(self.export_to_json)

    return export_excel_btn, export_json_btn


def export_to_excel(self):
    """导出Excel文件"""
    try:
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出Excel文件",
            f"垃圾检测统计_{datetime.now().strftime('%Y%m%d_%H%M%S')}.xlsx",
            "Excel files (*.xlsx)"
        )

        if file_path:
            if ExportManager.export_to_excel(self.stats_data, file_path):
                QMessageBox.information(self, "成功", f"Excel文件已保存至:\n{file_path}")
            else:
                QMessageBox.warning(self, "错误", "Excel导出失败")
    except Exception as e:
        QMessageBox.warning(self, "错误", f"Excel导出失败:\n{str(e)}")


def export_to_json(self):
    """导出JSON文件"""
    try:
        file_path, _ = QFileDialog.getSaveFileName(
            self, "导出JSON文件",
            f"垃圾检测数据_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json",
            "JSON files (*.json)"
        )

        if file_path:
            if ExportManager.export_to_json(self.stats_data, file_path):
                QMessageBox.information(self, "成功", f"JSON文件已保存至:\n{file_path}")
            else:
                QMessageBox.warning(self, "错误", "JSON导出失败")
    except Exception as e:
        QMessageBox.warning(self, "错误", f"JSON导出失败:\n{str(e)}")


# 修改StatisticsWindow的create_bottom_controls方法
def create_bottom_controls(self, parent_layout):
    """创建底部控制区域"""
    controls_frame = QFrame()
    controls_frame.setFixedHeight(70)
    controls_layout = QHBoxLayout(controls_frame)
    controls_layout.setContentsMargins(20, 10, 20, 10)

    # 导出按钮组
    export_excel_btn = QPushButton("📊 导出Excel")
    export_excel_btn.setFixedHeight(50)
    export_excel_btn.clicked.connect(self.export_to_excel)

    export_json_btn = QPushButton("📄 导出JSON")
    export_json_btn.setFixedHeight(50)
    export_json_btn.clicked.connect(self.export_to_json)

    # 刷新按钮
    refresh_btn = QPushButton("🔄 刷新数据")
    refresh_btn.setFixedHeight(50)
    refresh_btn.clicked.connect(self.refresh_data)

    # 关闭按钮
    close_btn = QPushButton("❌ 关闭窗口")
    close_btn.setFixedHeight(50)
    close_btn.clicked.connect(self.close)

    controls_layout.addWidget(export_excel_btn)
    controls_layout.addWidget(export_json_btn)
    controls_layout.addStretch()
    controls_layout.addWidget(refresh_btn)
    controls_layout.addWidget(close_btn)

    parent_layout.addWidget(controls_frame)


def _create_results_analysis_group(self):
    """创建实时检测结果分析组"""
    self.groupBox_2 = QtWidgets.QGroupBox(self.frame_2)
    self.groupBox_2.setGeometry(QtCore.QRect(10, 250, 341, 490))
    font = QtGui.QFont()
    font.setFamily("微软雅黑")
    font.setPointSize(12)
    font.setBold(True)
    font.setWeight(75)
    self.groupBox_2.setFont(font)
    self.groupBox_2.setObjectName("groupBox_2")
    self.groupBox_2.setTitle("实时检测结果分析")

    # 创建表单布局
    results_layout = QtWidgets.QFormLayout(self.groupBox_2)  # 确保创建了results_layout
    results_layout.setContentsMargins(10, 20, 10, 10)
    results_layout.setSpacing(8)

    # 检测结果表格
    self.tableWidget = QtWidgets.QTableWidget(self.groupBox_2)
    self.tableWidget.setRowCount(0)
    self.tableWidget.setColumnCount(5)

    # 设置表头
    header_labels = ["序号", "图片路径", "检测类别", "置信度", "坐标位置"]
    self.tableWidget.setHorizontalHeaderLabels(header_labels)

    # 设置表格属性
    self.tableWidget.horizontalHeader().setStretchLastSection(True)
    self.tableWidget.setAlternatingRowColors(True)
    self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
    self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)

    # 设置列宽
    self.tableWidget.setColumnWidth(0, 50)  # 序号
    self.tableWidget.setColumnWidth(1, 120)  # 图片路径
    self.tableWidget.setColumnWidth(2, 80)  # 检测类别
    self.tableWidget.setColumnWidth(3, 70)  # 置信度
    self.tableWidget.setColumnWidth(4, 100)  # 坐标位置

    # 添加表格到布局
    results_layout.addRow(self.tableWidget)

    # 创建统计按钮
    self.stats_btn = QtWidgets.QPushButton()
    self.stats_btn.setObjectName("stats_btn")
    self.stats_btn.setText("📊 数据统计分析")
    font_btn = QtGui.QFont()
    font_btn.setFamily("微软雅黑")
    font_btn.setPointSize(12)
    font_btn.setBold(True)
    self.stats_btn.setFont(font_btn)
    self.stats_btn.setMinimumHeight(45)
    self.stats_btn.setMaximumHeight(45)
    self.stats_btn.setStyleSheet("""
        QPushButton {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                stop:0 #7ed321, stop:1 #a8e063);
            border: none;
            border-radius: 8px;
            color: white;
            font-weight: bold;
            margin: 5px;
        }
        QPushButton:hover {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1, 
                stop:0 #a8e063, stop:1 #7ed321);
        }
        QPushButton:pressed {
            background: #5ba315;
        }
    """)

    # 添加统计按钮到布局
    results_layout.addRow(self.stats_btn)  # 现在results_layout已经定义了

    return self.groupBox_2


if __name__ == "__main__":
    """
    统计窗口测试代码
    """
    import sys
    from PyQt5.QtWidgets import QApplication, QTableWidget, QTableWidgetItem

    app = QApplication(sys.argv)

    # 创建测试数据
    test_table = QTableWidget()
    test_table.setColumnCount(5)
    test_table.setRowCount(10)

    # 填充测试数据
    test_data = [
        ("test1.jpg", "plastic-bag", "85.5", "[100, 120, 200, 250]"),
        ("test2.jpg", "bottle", "92.3", "[150, 80, 220, 180]"),
        ("test3.jpg", "plastic-garbage", "78.9", "[300, 200, 400, 320]"),
        ("test4.jpg", "leaf", "65.2", "[50, 50, 100, 100]"),
        ("test5.jpg", "branch", "71.8", "[200, 150, 280, 200]"),
    ]

    for i, (path, category, conf, coords) in enumerate(test_data * 2):  # 复制数据
        test_table.setItem(i, 1, QTableWidgetItem(f"test_{i}.jpg"))
        test_table.setItem(i, 2, QTableWidgetItem(category))
        test_table.setItem(i, 3, QTableWidgetItem(f"{float(conf) + i * 2:.1f} %"))
        test_table.setItem(i, 4, QTableWidgetItem(coords))

    # 创建统计窗口
    stats_window = StatisticsWindow(None, test_table)
    stats_window.show()

    sys.exit(app.exec_())

